#ifndef GRAPHICS_MATRIX_STACK_H
#define GRAPHICS_MATRIX_STACK_H

#include <stack>

#include "graphics/basic.h"

namespace graphics{

class MatrixStack{
public:
    MatrixStack() : cumulative_(cml::identity_4x4()), dirty_(false) {};    
    
    void Empty() {
        stack_.empty();
        cumulative_ = cml::identity_4x4();
        dirty = false;
    }
    void Push(const Matrix & matrix){
        stack_.push(matrix);

        //if not currently dirty, its a cheap matter to stay clean
        //so just do it
        if(!dirty)
            cumulative_ *= matrix;        

        //otherwise,stay dirty
    }

    void Pop() {
        stack_.pop();

        //don't bother re-calculating the cumulative effect
        //chances are high we will likely be popping others
        dirty = true;
    }

    const & Matrix Top() const { 
        if(dirty_) 
            CalculateCumulative(); 
        return cumulative_; 
    }

    uint32 Size() const {return stack_.size();}

    Matrix & operator[](const int & index){return stack_[index];}
    const Matrix operator[](const int & index){return stack_[index];}

private:
    void CalculateCumulative(){
        cumulative_ = cml::identity_4x4();
        for(size_t i = 0; i < stack_.size(); i++)
            cumulative *= stack_[i];
                
        dirty = false;
    }
    std::stack<Matrix> stack_;
    Matrix cumulative_;
    bool dirty_;
};

}
#endif